//可变参数模板是C++11新增的最强大的特性之一，它对参数进行了泛化
//能支持任意个数，任意数据类型的参数

#include<iostream>
using namespace std;

void print()	//需要自定义中止函数：1.不能有参数，表示没有参数时调用这个函数
{						//2.非模板函数  3.必须有，否则运行报错
	cout << "递归中止。" << endl;
}

//总体思路是用递归函数把参数包一次一次的展开
template<typename T, typename ...Args>
void print(T arg, Args... args)		//表示多个参数
{		//第一个参数arg表示展开的参数，即取出来的参数，第二个形参表示尚未展开的参数包
	cout << "参数: " << arg << endl;
	cout << "还有" << sizeof...(args) << "个参数未展开。" << endl; // 可以显示参数包中未展开变参的个数
	print(args...);		//递归继续展开参数(同样是多个参数)
}
int main()
{
	
	print("张三", 20, "男");
	return 0;
}

/*
参数: 张三
还有2个参数未展开。
参数: 20
还有1个参数未展开。
参数: 男
还有0个参数未展开。
递归中止。
*/








//也可以定义从第二个参数开始才接受可变参数
#include<iostream>
using namespace std;


template<typename T>
void show(T x)
{
	cout << "hello! " << x << endl;
}

void print()
{
	cout << "请多多关照。" << endl;
}

template<typename T, typename ...Args>
void print(T arg, Args... args)		
{
	show(arg);
	print(args...);		
}

template<typename ...Args>
void func(const string& str, Args ...args)
{
	cout << "大家好，我叫" << str << endl;
	print(args...);
	cout << "再见" << endl;
}

int main()
{
	//要求第一个实参必须是自己的名字即sting
	//需要定义一个普通模板再套一个递归模板
	func("李雷","张三", 20, "李四");
	return 0;
}
/*
大家好，我叫李雷
hello! 张三
hello! 20
hello! 李四
请多多关照。
再见
*/